import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_mvvm/utils/logger.dart';
import 'package:provider/provider.dart';

import 'base_entities.dart';
import 'base_error.dart';

///接口返回值回调
typedef BaseEntityRespFunc<T> = Future<BaseEntity<T>> Function();

///错误处理的handler
///true：表示已经处理了，不需要继续传递；false：表示需要继续传递处理。
typedef ErrorInterceptor = bool Function(BaseError error);

///viewModel基类
abstract class BaseViewModel extends ChangeNotifier {
  final CancelToken cancelToken = CancelToken();
  ErrorInterceptor _errorInterceptor;
  bool _isDisposed = false;
  int _loadingCount = 0;

  void onCreated();

  @override
  void dispose() {
    this.cancelToken.cancel();
    this._isDisposed = true;
    super.dispose();
  }

  @override
  void notifyListeners() {
    if (!_isDisposed) {
      super.notifyListeners();
    }
  }

  void showToast(String msg) {
    if (msg == null || msg.isEmpty) {
      return;
    }
    EasyLoading.showToast(msg, duration: Duration(seconds: 2));
  }

  ///绑定错误处理的拦截器
  void bindErrorInterceptor(ErrorInterceptor interceptor) {
    this._errorInterceptor = interceptor;
  }

  ///是否显示loading，内置loading计数器
  void _showLoading(bool isShow) {
    if (isShow) {
      _loadingCount++;
      if (_loadingCount == 1 && !EasyLoading.isShow) {
        EasyLoading.show();
      }
    } else {
      _loadingCount--;
      if (_loadingCount < 0) {
        _loadingCount = 0;
      }
      if (_loadingCount == 0 && EasyLoading.isShow) {
        EasyLoading.dismiss();
      }
    }
  }

  ///处理错误
  void _handleError(BaseError error) {
    //登录过期
    if (error.code == "500001") {
      showToast("登录已过期");
      return;
    }
    Logger.log(error.toString());
    if (_errorInterceptor != null && _errorInterceptor.call(error)) {
      return;
    }
    showToast(error.msg);
  }

  ///处理网络请求结果的函数，用于拦截异常、业务判断成功与否等
  ///[tryBlock] 处理结果，内置try-catch
  ///[onSuccess] 业务成功的回调
  ///[enableLoading] 本次是否使用loading
  void launchFutureBaseEntity<T>(BaseEntityRespFunc<T> tryBlock,
      {void onSuccess(BaseEntity<T> value), bool enableLoading = true}) {
    try {
      if (enableLoading) _showLoading(true);
      Future<BaseEntity<T>> resp = tryBlock();
      resp.then((BaseEntity<T> value) {
        if (enableLoading) _showLoading(false);
        if (value.isSuccess()) {
          if (onSuccess != null) {
            onSuccess(value);
          }
        } else {
          _handleError(BaseError(value.code, value.message));
        }
      }, onError: (e) {
        if (enableLoading) _showLoading(false);
        _handleError(BaseError(BaseError.CODE_EXCEPTION_MSG, e.toString()));
      });
    } catch (e) {
      if (enableLoading) _showLoading(false);
      _handleError(BaseError(BaseError.CODE_EXCEPTION_MSG, e.toString()));
    }
  }
}

///页面state基类
abstract class BaseState<T extends StatefulWidget> extends State<T> {
  void push(BuildContext context, Widget nexWidget) {
    Navigator.of(context)
        .push(CupertinoPageRoute(builder: (BuildContext context) {
      return nexWidget;
    }));
  }

  void pop(BuildContext context) {
    Navigator.of(context).pop();
  }

  void pushAndRemoveAll(BuildContext context, Widget nextWidget) {
    Navigator.of(context).pushAndRemoveUntil(
      CupertinoPageRoute(builder: (BuildContext context) {
        return nextWidget;
      }),
      (route) => false,
    );
  }
}

///内容view脚手架
// ignore: must_be_immutable
class BaseView<T extends BaseViewModel> extends StatefulWidget {
  Widget Function(BuildContext context, T viewModel, Widget child)
      _consumerBuilder;
  final Widget Function(BuildContext context, T viewModel) builder;

  final T viewModel;
  final Function(T) onViewModelCreated;

  BaseView({
    Key key,
    @required this.viewModel,
    this.onViewModelCreated,
    @required this.builder,
  }) : super(key: key) {
    this._consumerBuilder = (BuildContext context, T viewModel, Widget child) {
      return builder.call(context, viewModel);
    };
  }

  @override
  State<StatefulWidget> createState() => _BaseViewState<T>();
}

///内容view的state
class _BaseViewState<T extends BaseViewModel> extends State<BaseView<T>> {
  @override
  void initState() {
    super.initState();
    if (widget.onViewModelCreated != null && widget.viewModel != null) {
      widget.onViewModelCreated(widget.viewModel);
      widget.viewModel.onCreated();
    }
  }

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<T>(
        child: Consumer<T>(
          builder: widget._consumerBuilder,
        ),
        create: (BuildContext context) {
          return widget.viewModel;
        });
  }
}
